/*
 *  $Id: PolarPoint.cs 1224 2010-12-05 13:13:53Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2010 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System;

using AgateLib.Geometry;

namespace Ragima.Helper {
    /// <summary>
    /// Точка в полярных координатах.
    /// </summary>
    public struct PolarPoint {
        private double _angle;
        private double _radius;

        /// <summary>
        /// Создает полярную точку по углу и радиусу.
        /// </summary>
        public PolarPoint(double angle, double radius) {
            _angle = angle.NormalizeAngle();
            _radius = Math.Max(radius, 0);
        }

        /// <summary>
        /// Угол точки.
        /// </summary>
        public double Angle {
            get { return _angle; }
            set { _angle = value.NormalizeAngle(); }
        }

        /// <summary>
        /// Радиус точки.
        /// </summary>
        public double Radius {
            get { return _radius; }
            set { _radius = Math.Max(value, 0); }
        }

        /// <summary>
        /// Изменяет точку на указанные значения угла и радиуса.
        /// </summary>
        public void ChangeBy(double angle, double radius) {
            if (angle != 0)
                Angle += angle;
            if (radius != 0)
                Radius += radius;
        }

        /// <summary>
        /// Переводит в точку в декартовых координатах.
        /// </summary>
        public Point ToPoint() {
            if (_radius == 0)
                return Point.Empty;
            var a = _angle.ToRadians();
            var x = (int) Math.Round(_radius * Math.Cos(a));
            var y = (int) Math.Round(_radius * Math.Sin(a));
            return new Point(x, y);
        }

        /// <summary>
        /// Переводит в точку в декартовых координатах с указанным центром.
        /// </summary>
        public Point ToPoint(Point center) {
            if (_radius == 0)
                return center;
            return ToPoint().Add(center);
        }

        /// <summary>
        /// Переводит в точку в декартовых координатах.
        /// </summary>
        public PointF ToPointF() {
            if (_radius == 0)
                return PointF.Empty;
            var a = _angle.ToRadians();
            var x = (float) Math.Round(_radius * Math.Cos(a));
            var y = (float) Math.Round(_radius * Math.Sin(a));
            return new PointF(x, y);
        }

        /// <summary>
        /// Переводит в точку в декартовых координатах с указанным центром.
        /// </summary>
        public PointF ToPointF(PointF center) {
            if (_radius == 0)
                return center;
            return ToPointF().Add(center);
        }
    }
}
